//
//  NSObject+Localization.swift
//  PMS
//
//  Created by 何海涛 on 16/6/28.
//  Copyright © 2016年 途家. All rights reserved.
//

import Foundation

/**
 *  define action for different language.
 */
@objc public protocol ICustomLocalizationProtocol {
    func localizationOfDefault()
    // 定义特定语言行为时注意命名：
    // 1 localization_{language}
    // 2 language中的-替换为_
    @objc optional func localization_zh()
    @objc optional func localization_en()
}

extension NSObject {
    
    /**
     apply localization action
     */
    public func applyCustomLocalization() {
        if let iclp = self as? ICustomLocalizationProtocol {
            if let lang = CustomLocalizationHelper.currentLanguage {
                for selector in CustomLocalizationHelper.getAllAncestorLanguageSelectors(lang, prefix: "localization") {
                    // find specific localization action, execute this action and return.
                    if self.responds(to: selector) {
                        self.perform(selector)
                        return
                    }
                }
            }
            // fallback to execute default action.
            iclp.localizationOfDefault()
        }
    }
}

/// maybe we can use this manager to do some localization control.
// Localization是否要做不区分大小写的工作？？？如果要做，在这个类里实现就足够了。
public class CustomLocalizationHelper : NSObject {
    
    public class var currentLanguage : String? { return Locale.preferredLanguages.first }
    
    public class func isZh(_ lang: String) -> Bool {
        return isLangBelong(lang, to: "zh")
    }
    
    public class func isEn(_ lang: String) -> Bool {
        return isLangBelong(lang, to: "en")
    }
    
    public class func isLangBelong(_ lang: String, to : String) -> Bool {
        return lang.hasPrefix(to)
    }
    
    public class func isCurrentZh() -> Bool {
        return isZh(currentLanguage ?? "")
    }
    
    static public var languageAncestorCache = [String:[String]]()
    public class func getAllAncestorLanguages(_ lang: String) -> [String] {
        if let cache = languageAncestorCache[lang] {
            return cache
        }
        var result = [String]()
        if !lang.isEmpty {
            let components = Locale.components(fromIdentifier: lang)
            var combines = [[String: String]]()
            // 经过这个方法可能包含一些重复的组合，先不管
            getAllCombineOfOneElementRemoved(components, result: &combines)
            for combine in combines {
                let short = Locale.identifier(fromComponents: combine)
                // 仅保留有效的组合结果；并去除重复元素
                if !short.hasPrefix("_") && !result.contains(short) {
                    result.append(short)
                }
            }
            result.append(Locale.identifier(fromComponents: components))
        }
        languageAncestorCache[lang] = result
        return result
    }
    
    public class func getAllCombineOfOneElementRemoved(_ source: [String:String], result: inout [[String:String]]) {
        if source.count < 1 { return }
        for item in source {
            var copy = source
            copy.removeValue(forKey: item.0)
            result.append(copy)
            if copy.count > 1 {
                getAllCombineOfOneElementRemoved(copy, result: &result)
            }
        }
    }
    
    public class func convertLocaleIdentifier(_ lang: String) -> String {
        let componets = Locale.components(fromIdentifier: lang)
        return Locale.identifier(fromComponents: componets)
    }
    
    public class func getAllAncestorLanguageSelectors(_ lang: String, prefix: String) -> [Selector] {
        return getAllAncestorLanguages(lang).map({ (l) -> Selector in
            // 因为方法名不能有中横线，所以这里保险起见再把中横线替换一遍，改为下划线
            return Selector(String(format: "%@_%@", prefix, forceConvertToIdentifierString(l)))
        })
    }
    
    fileprivate class func forceConvertToIdentifierString(_ input : String) -> String {
        return input.replacingOccurrences(of: "-", with: "_")
    }
    
    fileprivate class func forceConvertFromIdentifierString(_ input : String) -> String {
        return input.replacingOccurrences(of: "_", with: "-")
    }
    
}

extension CustomLocalizationHelper {
    
    // 从词典资源中找出最适合指定语言的值。如当前语言是"zh-Hans" => 则会尝试查找 "zh_Hans" -> "zh" -> ""
    public class func findClosestValueForLanguage<T>(_ from: Dictionary<String, T>, lang: String?) -> T? {
        if from.count == 0 { return nil }
        
        let defaultLang = ""
        let source = getAllAncestorLanguages(lang ?? defaultLang)
        for l in source {
            if let val = from[l] ?? from[forceConvertFromIdentifierString(l)] {
                return val
            }
        }
        return from[defaultLang]
    }
    
    public class func findClosestValueForCurrentLanguage<T>(_ from: Dictionary<String,T>) -> T? {
        return findClosestValueForLanguage(from, lang: currentLanguage)
    }
    
    public class func runClosestActionForCurrentLanguage(_ from: Dictionary<String, ()->Void>) {
        findClosestValueForCurrentLanguage(from)?()
    }
    
    public class func runClosetActionForCurrentLanguage<T>(_ from: Dictionary<String, ()->T>) -> T? {
        return findClosestValueForCurrentLanguage(from)?()
    }
}
